package com.fy.fyspace.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fy.fyspace.common.result.Result;
import com.fy.fyspace.common.utils.CreateImageCode;
import com.fy.fyspace.common.utils.EmailCodeSend;
import com.fy.fyspace.common.utils.StringTools;
import com.fy.fyspace.constant.KeysConstant;
import com.fy.fyspace.constant.ResultMessageConstant;
import com.fy.fyspace.ex.ConditionException;
import com.fy.fyspace.ex.handler.ExceptionHandler;
import com.fy.fyspace.mapper.UserFeedBackMapper;
import com.fy.fyspace.model.dto.user.UserFeedbackDTO;
import com.fy.fyspace.model.entity.UserFeedback;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.messaging.MessagingException;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.fy.fyspace.constant.KeysConstant.CHECK_CODE;

@Slf4j
@Api(tags = "通用接口模块")
@RestController
public class CommonController {

    @Autowired
    private JavaMailSender javaMailSender;

    @Autowired
    private EmailCodeSend emailCodeSend;

    @Autowired
    private UserFeedBackMapper userFeedBackMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 图形验证码生成
     *
     * @param response
     * @param httpSession
     * @throws IOException
     */
    @ApiOperation(value = "生成验证码", notes = "生成验证码")
    @GetMapping("/checkCode")
    public void checkCode(HttpServletResponse response, HttpSession httpSession) throws IOException {
        CreateImageCode vCode = new CreateImageCode(120, 38, 4, 12);
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");
        String code = vCode.getCode();

        httpSession.removeAttribute(CHECK_CODE);

        httpSession.setAttribute(CHECK_CODE, code);
        httpSession.setMaxInactiveInterval(60);

        vCode.write(response.getOutputStream());
        log.info("生成验证码图片成功，验证码: {}", code);
    }

    /***
     * 发送验证码
     *
     * @param httpSession
     * @param checkCode
     * @return
     */
    @ApiOperation(value = "发送验证码", notes = "发送验证码")
    @PostMapping("/sendCode")
    public Result sendEmailCode(HttpSession httpSession, @RequestParam("checkCode") String checkCode) {
        log.info("ll:{}", httpSession.getAttribute(CHECK_CODE), checkCode);
        if (checkCode.equalsIgnoreCase((String) httpSession.getAttribute(CHECK_CODE))) {
            httpSession.removeAttribute(CHECK_CODE);
            return Result.success();
        } else {
            httpSession.removeAttribute(CHECK_CODE);
            ExceptionHandler.throwIf(ResultMessageConstant.CAPTCHA_ERROR);
            return Result.success();
        }
    }

    /**
     * 发送邮箱验证码
     * @param httpSession
     * @param email
     * @param checkCode
     * @return
     */
    @PostMapping("/sendEmailCode")
    @ApiOperation(value = "发送邮箱验证码", notes = "发送邮箱验证码")
    public Result sendEmailCode(HttpSession httpSession, String email, @RequestParam("checkCode") String checkCode) {
        String sessionCode = (String) httpSession.getAttribute(KeysConstant.CHECK_CODE);
        log.info("本地和前端验证码:{}，{}", sessionCode, checkCode);

        if (checkCode.equalsIgnoreCase(sessionCode)) {
            String redisKey = KeysConstant.CHECK_CODE_EMAIL + email;
            String existingCode = stringRedisTemplate.opsForValue().get(redisKey);

            if (existingCode != null) {
                // 获取剩余过期时间（秒）
                Long expireTime = stringRedisTemplate.getExpire(redisKey, TimeUnit.SECONDS);
                if (expireTime != null && expireTime > 0) {
                    throw new ConditionException(String.format("操作过于频繁，请在%d秒后再试", expireTime));
                }
            }

            httpSession.removeAttribute(KeysConstant.CHECK_CODE);
            String code = StringTools.getRandomNumber(6);
            log.info("邮箱验证码为:{}", code);

            try {
                javaMailSender.send(emailCodeSend.packageMessage(email, code, 300));

                httpSession.setAttribute(KeysConstant.CHECK_CODE_EMAIL, code);
                httpSession.setMaxInactiveInterval(300);
                
                stringRedisTemplate.opsForValue().set(redisKey, code, 60, TimeUnit.SECONDS);
                return Result.success();
            } catch (MessagingException e) {
                log.error("邮件发送失败", e);
                throw new RuntimeException("邮件发送失败: " + e.getMessage());
            } catch (javax.mail.MessagingException e) {
                throw new RuntimeException(e);
            }
        } else {
            httpSession.removeAttribute(KeysConstant.CHECK_CODE);
            throw new ConditionException(ResultMessageConstant.CAPTCHA_ERROR);
        }
    }

    /**
     * 用户提交反馈
     * @param userFeedbackDTO
     * @return
     */
    @PostMapping("/feedback/submit")
    @ApiOperation(value = "提交反馈", notes = "用户提交反馈")
    public Result submitFeedback(@RequestBody UserFeedbackDTO userFeedbackDTO) {
        ExceptionHandler.throwIf(userFeedbackDTO == null, ResultMessageConstant.PARAMS_ERROR);

        UserFeedback userFeedback = new UserFeedback();
        if (userFeedbackDTO.getType() != null) {
            userFeedback.setType(userFeedbackDTO.getType());
        }
        if (userFeedbackDTO.getDescription() != null) {
            userFeedback.setDescription(userFeedbackDTO.getDescription());
        }
        if (userFeedbackDTO.getContact() != null) {
            userFeedback.setContact(userFeedbackDTO.getContact());
        }
        userFeedback.setCreateTime(new Date());
        userFeedback.setIsRead(0);
        userFeedBackMapper.insertOrUpdate(userFeedback);
        return Result.success();
    }

    /**
     * 获取用户反馈列表
     * 排序规则：1. 未读在前，已读在后 2. 同一读取状态内按创建时间倒序排序
     */
    @ApiOperation(value = "获取用户反馈列表", notes = "分页获取用户的反馈列表")
    @GetMapping("/feedback/list")
    public Result getUserFeedbackList(@RequestParam(required = false) Integer page,
                                    @RequestParam(required = false) Integer pageSize,
                                    @RequestParam(required = false) String type) {
        try {
            log.info("获取用户反馈列表: page={}, pageSize={}, type={}", page, pageSize, type);
            
            // 设置默认值
            page = page == null ? 1 : page;
            pageSize = pageSize == null ? 10 : pageSize;

            // 构建查询条件
            LambdaQueryWrapper<UserFeedback> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StringUtils.isNotBlank(type), UserFeedback::getType, type)
                    // 先按已读状态升序（未读在前），再按创建时间倒序
                    .orderByAsc(UserFeedback::getIsRead)
                    .orderByDesc(UserFeedback::getCreateTime);

            // 执行分页查询
            Page<UserFeedback> feedbackPage = new Page<>(page, pageSize);
            Page<UserFeedback> resultPage = userFeedBackMapper.selectPage(feedbackPage, wrapper);

            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("total", resultPage.getTotal());
            result.put("records", resultPage.getRecords()); // 改为records以保持一致性

            log.info("获取用户反馈列表成功: total={}, 当前页数据量={}", 
                    resultPage.getTotal(), resultPage.getRecords().size());
            return Result.success(result);

        } catch (Exception e) {
            log.error("获取用户反馈列表失败: error={}", e.getMessage());
            return Result.error(ResultMessageConstant.OPERATION_ERROR);
        }
    }

    /**读取反馈详情
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "获取反馈详情", notes = "读取反馈详情")
    @GetMapping("/feedback/detail/{id}")
    public Result getFeedbackDetail(@PathVariable Long id) {
        try {
            log.info("获取反馈详情: id={}", id);

            // 查询反馈信息
            UserFeedback feedback = userFeedBackMapper.selectById(id);
            ExceptionHandler.throwIf(feedback == null,"反馈不存在");

            // 更新已读状态
            if (feedback.getIsRead() == 0) {
                feedback.setIsRead(1);
                feedback.setCreateTime(new Date());
                userFeedBackMapper.updateById(feedback);
                log.info("更新反馈已读状态: id={}", id);
            }

            log.info("获取反馈详情成功: id={}", id);
            return Result.success(feedback);

        } catch (Exception e) {
            log.error("获取反馈详情失败: id={}, error={}", id, e.getMessage());
            return Result.error(ResultMessageConstant.OPERATION_ERROR);
        }
    }
}
